h1b_df <- DATA

SECTION 1: BACKGROUND

SLIDE 7: MAP

DATA_certificate <- DATA %>%
  filter(case_status == "certified") %>%
  group_by(worksite_state_abb, year) %>%
  summarise(num = n())
DATA_new <-  DATA_certificate %>%
  ungroup(worksite_state_abb) %>%
  mutate(worksite_state_abb = str_to_upper(worksite_state_abb))
d1 <-
  ichoropleth(
    num ~ worksite_state_abb,
    data = DATA_new,
    animate = 'year',
    ncuts = 9,
    legend = FALSE,
    geographyConfig = list(popupTemplate = "#!function(geo, data) {return '<div class=\"hoverinfo\"><strong>' + data.worksite_state_abb + '<br>' + data.num + '</strong></div>';}!#")
  )
d1$save('rMaps.html', cdn = TRUE)
htmltools::includeHTML("rMaps.html")

SECTION 2: STEM

SLIDE 9: Stem and non-stem histogram

DATA %>%
  group_by(year, stem) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n, fill = as.factor(stem))) +
  geom_bar(stat = "identity",
           position = position_stack(reverse = FALSE),
           alpha = 0.8) +
  scale_fill_manual(
    values = c("#00B2E4", "#0F2A48"),
    name = "",
    labels = c("non-STEM", "STEM")
  ) +
  labs(y = "\n Number", x = "\n Year") +
  scale_y_continuous(
    labels = function(x) {
      paste0(x / 1000, 'K')
    }
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(legend.position = "top")

SLIDE 10: STEM and non-STEM boxplot: “Prevailing wage boxplot throughout years”

DATA %>%
  filter(prevailing_wage >= 0 & prevailing_wage <= 600000) %>%
  ggplot(aes(x = as.factor(year), y = prevailing_wage)) +
  geom_boxplot(
    aes(fill = as.factor(stem)),
    outlier.shape = NA,
    alpha = 0.9,
    color = "white"
  ) +
  theme_minimal() +
  labs(x = "\n Year", y = "Prevailing wage \n") +
  scale_y_continuous(
    labels = function(x) {
      paste0(x / 1000, "K")
    }
  ) +
  scale_color_manual(
    values = c("#00B2E4", "#0F2A48"),
    name = "",
    labels = c("non-STEM", "STEM")
  ) +
  scale_fill_manual(
    values = c("#00B2E4", "#0F2A48"),
    name = "",
    labels = c("non-STEM", "STEM")
  ) +
  coord_cartesian(ylim = c(40000, 100000))

SLIDE 11: Stem and non-stem prevailing wage distribution in 2018

DATA %>%
  filter(year == 2018) %>%
  filter(prevailing_wage >= 0 & prevailing_wage <= 400000) %>%
  ggplot(aes(
    x = prevailing_wage,
    color = as.factor(stem),
    fill = as.factor(stem)
  )) +
  geom_density(adjust = 2, alpha = 0.7) +
  theme_classic() +
  labs(x = "\n Prevailing wage ($)",
       y = expression(Density ~ (10 ^ {
         -3
       })),
       title = "") +
  scale_x_continuous(
    labels = function(x) {
      paste0(x / 1000, 'K')
    }
  ) +
  scale_y_continuous(
    labels = function(x) {
      paste0(x * 1000, "")
    }
  ) +
  scale_color_manual(
    values = c("#00B2E4", "#0F2A48"),
    name = "",
    labels = c("non-STEM", "STEM")
  ) +
  scale_fill_manual(
    values = c("#00B2E4", "#0F2A48"),
    name = "",
    labels = c("non-STEM", "STEM")
  ) +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_minimal()

SLIDE 12 AND 13: bar plot: stem jobs

dt <- DATA %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "business") &
      (
        str_detect(job_title, "analyst") |
          str_detect(job_title, "intelligence")
      ) ,
    "business analyst",
    job_title
  )) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "data") &
      (
        str_detect(job_title, "engineer") |
          str_detect(job_title, "warehouse")
      ),
    "data engineer",
    job_title
  )) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "data") &
      str_detect(job_title, "scientist"),
    "data scientist",
    job_title
  )) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "data") &
      str_detect(job_title, "analyst|analytics"),
    "data analyst",
    job_title
  )) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "machine|deep") &
      str_detect(job_title, "learning"),
    "deep learning & machine learning",
    job_title
  )) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "product") &
      str_detect(job_title, "analyst|engineer|data"),
    "data product analyst",
    job_title
  )) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, "senior systems analyst jc60"),
    "senior systems analyst",
    job_title
  )) %>%
  filter(stem == 1)

dt %>%
  filter(year == 2018) %>%
  group_by(job_title) %>%
  summarise(n = n()) %>%
  arrange(-n) %>%
  slice(1:20) %>%
  mutate(cat = ifelse(str_detect(job_title, "analyst|data"), "data", "non-data")) %>%
  arrange(n) %>%
  ggbarplot(
    "job_title",
    "n",
    fill = "cat",
    palette = c("#FC2967", "#00B2E4"),
    alpha = 0.8,
    orientation = "horiz",
    color = "white"
  ) +
  labs(y = "Number of Aplications", x = "Job Titles") +
  theme_minimal() +
  theme(legend.position = "none") +
  theme(panel.grid.major.y = element_blank())



# original
dt %>%
  filter(year == 2018) %>%
  group_by(job_title) %>%
  summarise(n = n()) %>%
  arrange(-n) %>%
  slice(1:20) %>%
  mutate(cat = ifelse(str_detect(job_title, "analyst|data"), "data", "non-data")) %>%
  arrange(n) %>%
  ggbarplot(
    "job_title",
    "n",
    fill = "#00B2E4",
    alpha = 0.8,
    orientation = "horiz",
    color = "white"
  ) +
  labs(y = "Number of Aplications", x = "Job Titles") +
  theme_minimal() +
  theme(panel.grid.major.y = element_blank())

Slide 15

dt <- DATA %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Engineer",
      "Data Analyst",
      "Data Scientist"
    )
  ) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)

p1 <- dt %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2)+
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "Applications Data related jobs",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))
p1

slide 16

filtered_job <- DATA %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Engineer",
      "Data Scientist",
      "Data Analyst"
    )
  )


filtered_job$data_job_title <-
  factor(
    filtered_job$data_job_title,
    levels = c(
      "Data Analyst",
      "Business Analyst",
      "Data Engineer",
      "Data Scientist"
    ),
    ordered = TRUE
  )


filtered_job %>% group_by(data_job_title) %>% summarise(mean = mean(prevailing_wage))
filtered_job %>%
  ggplot(aes(y = prevailing_wage, x = data_job_title)) +
  geom_boxplot(
    fill = "#00B2E4",
    outlier.shape = NA,
    color = "white",
    width = 0.5
  ) +
  coord_cartesian(ylim = c(50000, 120000)) +
  theme_minimal() +
  labs(x = "\n Job title", y = "Prevailing wage (per year) \n", title = "Prevailing wages in data related jobs") +
  theme(
    plot.title = element_text(size = 1),
    text = element_text(size = 12),
    axis.title = element_text(size = 16),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Slide 17

top_com <- DATA %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Analyst",
      "Data Engineer",
      "Data Scientist"
    )
  ) %>%
  group_by(employer_name) %>%
  summarise(n = n()) %>%
  arrange(-n) %>%
  slice(1:20) %>%
  ungroup()

top_com <- top_com$employer_name

spa_data <- DATA %>%
  filter(employer_name %in% top_com) %>%
  filter(employer_name != "capgemini america inc") %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Analyst",
      "Data Engineer",
      "Data Scientist"
    )
  ) %>%
  group_by(employer_name, year) %>%
  summarise(n = n())

con = c("infosys limited",
        "deloitte consulting llp",
        "amazon",
        "facebook",
        "ibm")
myColor <- c("#465881", "#FFB6C1", "#00909e", "#00B2E4", "#FC2967")

# c(amazon, "deloitte", "#facebook", "ibm", "info")

ggplot(spa_data, aes(x = year, y = n, group = employer_name)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(x = "Year",
       y = "Number",
       col = "") +
  theme_classic() +
  geom_line(
    data = subset(spa_data, employer_name %in% con),
    aes(col = employer_name),
    size = 1.2
  ) +
  theme(
    plot.title = element_text(size = 14),
    text = element_text(size = 12),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11)
  ) +
  scale_color_manual(
    values = myColor,
    breaks = c(
      "infosys limited",
      "deloitte consulting llp",
      "amazon",
      "facebook",
      "ibm"
    ),
    labels = c(
      "Infosys Limited",
      "Deloitte Consulting",
      "Amazon",
      "Facebook",
      "IBM"
    )
  )  +
  theme_minimal() +
  theme(legend.position = "right")

Slide 17

Data jobs in top companies

filtered_job_all <- DATA %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Analyst",
      "Data Engineer",
      "Data Scientist"
    )
  ) %>%
  mutate(employer_name = ifelse(
    str_detect(employer_name, 'apple'),
    'Apple',
    ifelse(
      str_detect(employer_name, 'microsoft'),
      'Microsoft',
      ifelse(
        str_detect(employer_name, 'amazon'),
        'Amazon',
        ifelse(
          str_detect(employer_name, 'facebook'),
          'Facebook',
          ifelse(
            str_detect(employer_name, 'google'),
            'Google',
            ifelse(str_detect(employer_name, 'ibm'), 'IBM', employer_name)
          )
        )
      )
    )
  )) 
  

#IBM

top_com <- DATA %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Analyst",
      "Data Engineer",
      "Data Scientist"
    )
  ) %>%
  group_by(employer_name) %>%
  summarise(n = n()) %>%
  arrange(-n) %>%
  slice(1:20) %>%
  ungroup()

top_com <- top_com$employer_name

ibm_data <- DATA %>%
  filter(str_detect(employer_name, "ibm")) %>%
  group_by(job_title, year) %>%
  summarise(n = n()) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "business") &
               (
                 str_detect(job_title, "analyst") |
                   str_detect(job_title, "intelligence")
               ),
             "Business Analyst",
             NA
           )) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "data") &
               (
                 str_detect(job_title, "engineer") |
                   str_detect(job_title, "warehouse")
               ),
             "Data Engineer",
             data_job_title
           )) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "data") & str_detect(job_title, "scientist"),
             "Data Scientist",
             data_job_title
           )) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "data") &
               str_detect(job_title, "analyst|analytics"),
             "Data Analyst",
             data_job_title
           )) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "machine|deep") &
               str_detect(job_title, "learning"),
             "Data Scientist",
             data_job_title
           )) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "product") &
               str_detect(job_title, "analyst|engineer|data"),
             "Data Analyst",
             data_job_title
           )) %>%
  mutate(data_job_title =
           ifelse(
             str_detect(job_title, "product") & str_detect(job_title, "manager"),
             "Product Manager",
             data_job_title
           ))

con = c("infosys limited",
        "deloitte consulting llp",
        "amazon",
        "facebook",
        "ibm")
myColor <- c("#465881", "#FFB6C1", "#00909e", "#00B2E4", "#FC2967")

# c(amazon, "deloitte", "#facebook", "ibm", "info")

ggplot(ibm_data, aes(x = year, y = n, group = job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(x = "Year",
       y = "Number",
       col = "") +
  theme_classic() +
  geom_line(
    data = subset(
      ibm_data,
      data_job_title %in% c(
        "Business Analyst",
        "Data Analyst",
        "Data Engineer",
        "Data Scientist"
      )
    ),
    aes(col = data_job_title),
    size = 1.2
  ) +
  theme(
    plot.title = element_text(size = 14),
    text = element_text(size = 12),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11),
    legend.position = "top",
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  ylim(0, 150)

filtered_job_all %>%
  filter(employer_name == 'IBM') %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

NA
NA

Infosys


filtered_job_all %>%
  filter(str_detect(employer_name, 'infosys')) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(legend.position = "top") +
  theme(plot.title = element_text(hjust = 0.5))

Accenture

filtered_job_all %>%
  filter(str_detect(employer_name, 'accenture')) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Microsoft

filtered_job_all %>%
  filter(employer_name == 'Microsoft') %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Amazon

filtered_job_all %>%
  filter(employer_name == 'Amazon') %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Deloitte

filtered_job_all %>%
  filter(str_detect(employer_name, "deloitte")) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Facebook

filtered_job_all %>%
  filter(str_detect(employer_name, "Facebook")) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Apple

filtered_job_all %>%
  filter(str_detect(employer_name, "Apple")) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Google

filtered_job_all %>%
  filter(str_detect(employer_name, "Google")) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = year, y = n)) +
  #geom_point(aes(color = data_job_title), size = 2) +
  geom_line(aes(color = data_job_title), size = 1.2) +
  labs(
    y = "",
    x = "Year",
    title = "",
    face = "bold",
    size = 14
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme_minimal() +
  theme(
    legend.position = "top",
    axis.text = element_text(size = 15),
    axis.title.x = element_text(size = 15)
  ) +
  theme(plot.title = element_text(hjust = 0.5))

Facebook

h1b_facebook <- h1b_df %>%
  filter(employer_name == 'facebook') %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)
  
con = c("Data Scientist",
        "software engineer",
        "Data Engineer",
        'research scientist')
ggplot(h1b_facebook, aes(x = year, y = n, group = data_job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(title = "H1B in Facebook",
       x = "Year",
       y = "Number",
       col = 'Job Title') +
  theme_light() +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_line(
    data = subset(h1b_facebook, data_job_title %in% con),
    aes(col = data_job_title),
    size = 0.7
  ) +
  theme(
    plot.title = element_text(
      size = 14,
      family = "Helvetica",
      face = "bold"
    ),
    text = element_text(size = 12, family = "Helvetica"),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11)
  ) +
  scale_color_discrete(labels = c(
    "Data Engineer",
    "Data Scientist",
    "Research Scientist",
    "Software Engineer"
  ))

Amazon

h1b_amazon <- h1b_df %>%
  filter(str_detect(employer_name, 'amazon')) %>%
  ungroup(data_job_title) %>%
  mutate(job_title = ifelse(
    str_detect(data_job_title, 'software development engineer'),
    'software development engineer',
    ifelse(
      str_detect(data_job_title, 'technical program manager'),
      'technical program manager',
      data_job_title
    )
  )) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)
con = c(
  "Data Scientist",
  "software development engineer",
  "business analyst",
  "Data Engineer",
  "technical program manager"
)
ggplot(h1b_amazon, aes(x = year, y = n, group = data_job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(title = "H1B in Amazon",
       x = "Year",
       y = "Number",
       col = 'Job Title') +
  theme_light() +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_line(
    data = subset(h1b_amazon, data_job_title %in% con),
    aes(col = data_job_title),
    size = 0.7
  ) +
  theme(
    plot.title = element_text(
      size = 14,
      family = "Helvetica",
      face = "bold"
    ),
    text = element_text(size = 12, family = "Helvetica"),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11)
  ) +
  scale_color_discrete(
    labels = c(
      "Business Analyst",
      "Data Engineer",
      "Data Scientist",
      "Software Development Engineer",
      "Technical Program Manager"
    )
  )

Microsoft

h1b_micro <- h1b_df %>%
  filter(str_detect(employer_name, 'microsoft')) %>%
  ungroup(data_job_title) %>%
  mutate(job_title = ifelse(
    str_detect(
      data_job_title,
      'software engineer|software development engineer'
    ),
    'software engineer',
    ifelse(
      str_detect(data_job_title, 'program manager'),
      'program manager',
      data_job_title
    )
  )) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)
  
con = c("Data Scientist", "software engineer", "program manager")
ggplot(h1b_micro, aes(x = year, y = n, group = data_job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(title = "H1B in Microsoft",
       x = "Year",
       y = "Number",
       col = 'Job Title') +
  theme_light() +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_line(
    data = subset(h1b_micro, data_job_title %in% con),
    aes(col = data_job_title),
    size = 0.7
  ) +
  theme(
    plot.title = element_text(
      size = 14,
      family = "Helvetica",
      face = "bold"
    ),
    text = element_text(size = 12, family = "Helvetica"),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11)
  ) +
  scale_color_discrete(labels = c("Data Scientist", "Program Manager", "Software Engineer"))

Google

h1b_google <- h1b_df %>%
  filter(str_detect(employer_name, 'google'))
h1b_google <- h1b_google %>%
  ungroup(job_title) %>%
  mutate(job_title = ifelse(
    str_detect(job_title, 'software engineer'),
    'software engineer',
    ifelse(
      str_detect(job_title, 'hardware engineer'),
      'hardware engineer',
      job_title
    )
  )) %>%
  group_by(job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)
con = c(
  "Data Scientist",
  "software engineer",
  "program manager",
  "product manager",
  "business analyst"
)
ggplot(h1b_google, aes(x = year, y = n, group = job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(title = "H1B in Google",
       x = "Year",
       y = "Number",
       col = 'Job Title') +
  theme_light() +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_line(
    data = subset(h1b_google, job_title %in% con),
    aes(col = job_title),
    size = 0.7
  ) +
  theme(
    plot.title = element_text(
      size = 14,
      family = "Helvetica",
      face = "bold"
    ),
    text = element_text(size = 12, family = "Helvetica"),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11)
  ) +
  scale_color_discrete(
    labels = c(
      "Business Analyst",
      "Data Scientist",
      "Product Manager",
      "Program Manager",
      "Software Engineer"
    )
  )

IBM

h1b_ibm <- h1b_df %>%
  filter(str_detect(employer_name, 'ibm'))
h1b_ibm <- h1b_ibm %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)
con = c("Business Analyst",
        "Data Engineer",
        "Data Scientist",
        "Data Analyst")
ggplot(h1b_ibm, aes(x = year, y = n, group = data_job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(title = "",
       x = "Year",
       y = "Number",
       col = 'Job Title') +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_line(
    data = subset(h1b_ibm, data_job_title %in% con),
    aes(col = data_job_title),
    size = 1.1
  ) +
  scale_color_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                     name = "") +
  theme(
    plot.title = element_text(size = 14, family = "Helvetica"),
    text = element_text(size = 12, family = "Helvetica"),
    #axis.title = element_text(face="bold"),
    axis.text.x = element_text(size = 11),
    legend.position = "none"
  ) +
  coord_cartesian(ylim = c(0, 1000))

Uber

h1b_uber <- h1b_df %>%
  filter(str_detect(employer_name, 'uber')) %>%
  ungroup(data_job_title) %>%
  mutate(data_job_title = ifelse(
    str_detect(data_job_title, 'software engineer'),
    'Software Engineer',
    data_job_title
  )) %>%
  group_by(data_job_title, year) %>%
  summarise(n = n()) %>%
  arrange(-n)
con = c("Software Engineer", "Data Scientist", "Data Analyst")
ggplot(h1b_uber, aes(x = year, y = n, group = data_job_title)) +
  geom_line(alpha = 0.3,
            size = 0.2) +
  labs(title = "H1B in Uber",
       x = "Year",
       y = "Number",
       col = 'Job Title') +
  theme_light() +
  theme(plot.title = element_text(hjust = 0.5)) +
  geom_line(
    data = subset(h1b_uber, data_job_title %in% con),
    aes(col = data_job_title),
    size = 0.7
  ) +
  theme(
    plot.title = element_text(
      size = 14,
      family = "Helvetica",
      face = "bold"
    ),
    text = element_text(size = 12, family = "Helvetica"),
    axis.title = element_text(face = "bold"),
    axis.text.x = element_text(size = 11)
  )

Data job per state in 2018

DATA_certificate_data <- DATA %>%
  filter(case_status == "certified") %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Engineer",
      "Data Analyst",
      "Data Scientist"
    )
  ) %>%
  group_by(worksite_state_abb, year) %>%
  summarise(num = n())
DATA_new_data <-  DATA_certificate_data %>%
  ungroup(worksite_state_abb) %>%
  mutate(worksite_state_abb = str_to_upper(worksite_state_abb))
d1 <-
  ichoropleth(
    num ~ worksite_state_abb,
    data = DATA_new_data,
    animate = 'year',
    ncuts = 8,
    legend = FALSE,
    geographyConfig = list(popupTemplate = "#!function(geo, data) {return '<div class=\"hoverinfo\"><strong>' + data.worksite_state_abb + '<br>' + data.num + '</strong></div>';}!#")
  )
d1$save('rMaps_data.html', cdn = TRUE)
htmltools::includeHTML("rMaps.html")

Alluvia

filtered_job <- DATA %>%
  filter(year == 2018) %>%
  filter(
    data_job_title %in% c(
      "Business Analyst",
      "Data Analyst",
      "Data Engineer",
      "Data Scientist"
    )
  )


top_10_state <- filtered_job %>%
  group_by(worksite_state_abb) %>%
  summarise(count = n()) %>%
  arrange(desc(count)) %>%
  slice(1:10)

flows <- filtered_job %>%
  filter(worksite_state_abb %in% top_10_state$worksite_state_abb) %>%
  group_by(data_job_title,
           worksite_state_abb) %>%
  summarise(count = n())


ggplot(flows,
       aes(y = count, axis1 = data_job_title, axis2 = worksite_state_abb)) +
  geom_alluvium(aes(fill = data_job_title)) +
  geom_stratum(
    width = 1 / 8,
    fill = "#0F2A48",
    color = "grey",
    alpha = 0.9
  ) +
  geom_label(stat = "stratum", label.strata = TRUE) +
  labs(x = "", y = "") +
  theme_minimal() +
  theme(legend.position = "top") +
  scale_fill_manual(values = c("#FC2967", "#465881", "#00909e", "#00B2E4"),
                    name = NULL) +
  scale_x_discrete(limits = c("Job title", "State"),
                   expand = c(.05, .05)) +
  theme(axis.text.x = element_text(size = 12, face = "bold")) +
  theme(line = element_blank())

bar plot:stem program in different job titles

DATA %>% 
  mutate(job_title = ifelse(str_detect(job_title, "business")& (str_detect(job_title, "analyst")|str_detect(job_title, "intelligence")) , "business analyst", job_title)) %>% 
  mutate(job_title = ifelse(str_detect(job_title, "data")& (str_detect(job_title, "engineer")|str_detect(job_title, "warehouse")), "data engineer", job_title)) %>% 
  mutate(job_title = ifelse(str_detect(job_title, "data")& str_detect(job_title, "scientist"), "data scientist", job_title)) %>% 
  mutate(job_title = ifelse(str_detect(job_title, "data")& str_detect(job_title, "analyst|analytics"), "data analyst", job_title)) %>% 
  mutate(job_title = ifelse(str_detect(job_title, "machine|deep")& str_detect(job_title, "learning"), "deep learning & machine learning", job_title)) %>% 
  mutate(job_title = ifelse(str_detect(job_title, "product") & str_detect(job_title, "analyst|engineer|data"), "data product analyst", job_title)) %>% 
  filter(year == 2018) %>% 
  filter(stem == 1) %>% 
  group_by(job_title) %>% 
  summarise(n = n()) %>%
  arrange(-n) %>% 
  slice(1:20) %>% 
  ggbarplot("job_title", "n", fill = "#00B2E4", color = "white", alpha = 0.8, sort.val = "asc", orientation = "horiz") %>% 
  labs(title = "stem program")

MAP - data job with the highest number in each city

ggplot(points) + 
  geom_sf(data = state_maps, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon,100), y = jitter(lat,100), color = max_job, size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        legend.box = "horizontal",
        legend.position = c(0,-0.1), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_ca) + 
  geom_sf(data = state_maps_ca, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon), y = jitter(lat), color = max_job, size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_tx) + 
  geom_sf(data = state_maps_tx, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon), y = jitter(lat), color = max_job, size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_northeast) + 
  geom_sf(data = state_maps_northeast, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon), y = jitter(lat), color = max_job, size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_midwest) + 
  geom_sf(data = state_maps_midwest, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon,100), y = jitter(lat,100), color = max_job, size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_tn) + 
  geom_sf(data = state_maps_tn, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon), y = jitter(lat), color = max_job,size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_fl) + 
  geom_sf(data = state_maps_fl, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon), y = jitter(lat), color = max_job,size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

ggplot(points_wa) + 
  geom_sf(data = state_maps_wa, color = "white", fill = "lightgrey",alpha=0.5) +
  geom_point(aes(x = jitter(lon), y = jitter(lat), color = max_job, size = max), alpha = 0.5) + 
  scale_color_manual(values = c("Business Analyst" = "#00B2E4", 
                                "Data Analyst" = "#0F2A48",
                                "Data Engineer" = "#008B8B",
                                "Data Scientist" = "#FC2967"),
                     name = "Job Title") +
  theme(panel.background = element_blank(),
        legend.background = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        #legend.position = c(0,0), legend.justification = c(0,0)
        )+
  labs(x = "", y = "", title = "", size="Number")

DATA %>%
  filter(worksite_state_abb == "TN") %>%
  group_by(year, data_relation) %>%
  summarise(n = n()) %>%
  
  ggplot(aes(
    x = year,
    y = n,
    fill = as.factor(data_relation)
  )) +
  geom_bar(stat = "identity",
           position = "dodge",
           alpha = 0.8) +
  scale_fill_manual(
    values = c("#00B2E4", "#0F2A48"),
    name = "",
    labels = c("Data jobs", "Others")
  ) +
  labs(y = "\n Number", x = "\n Year") +
  #scale_y_continuous(labels = function(x){paste0(x/1000, 'K')}) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(legend.position = "top")
LS0tCnRpdGxlOiAiRmluYWxfUmVwb3J0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKYGBge3J9CmgxYl9kZiA8LSBEQVRBCmBgYAoKCiMgU0VDVElPTiAxOiBCQUNLR1JPVU5ECiMgU0xJREUgNzogTUFQCmBgYHtyfQpEQVRBX2NlcnRpZmljYXRlIDwtIERBVEEgJT4lCiAgZmlsdGVyKGNhc2Vfc3RhdHVzID09ICJjZXJ0aWZpZWQiKSAlPiUKICBncm91cF9ieSh3b3Jrc2l0ZV9zdGF0ZV9hYmIsIHllYXIpICU+JQogIHN1bW1hcmlzZShudW0gPSBuKCkpCmBgYAoKYGBge3J9CkRBVEFfbmV3IDwtICBEQVRBX2NlcnRpZmljYXRlICU+JQogIHVuZ3JvdXAod29ya3NpdGVfc3RhdGVfYWJiKSAlPiUKICBtdXRhdGUod29ya3NpdGVfc3RhdGVfYWJiID0gc3RyX3RvX3VwcGVyKHdvcmtzaXRlX3N0YXRlX2FiYikpCmBgYAoKYGBge3J9CmQxIDwtCiAgaWNob3JvcGxldGgoCiAgICBudW0gfiB3b3Jrc2l0ZV9zdGF0ZV9hYmIsCiAgICBkYXRhID0gREFUQV9uZXcsCiAgICBhbmltYXRlID0gJ3llYXInLAogICAgbmN1dHMgPSA5LAogICAgbGVnZW5kID0gRkFMU0UsCiAgICBnZW9ncmFwaHlDb25maWcgPSBsaXN0KHBvcHVwVGVtcGxhdGUgPSAiIyFmdW5jdGlvbihnZW8sIGRhdGEpIHtyZXR1cm4gJzxkaXYgY2xhc3M9XCJob3ZlcmluZm9cIj48c3Ryb25nPicgKyBkYXRhLndvcmtzaXRlX3N0YXRlX2FiYiArICc8YnI+JyArIGRhdGEubnVtICsgJzwvc3Ryb25nPjwvZGl2Pic7fSEjIikKICApCmBgYAoKYGBge3J9CmQxJHNhdmUoJ3JNYXBzLmh0bWwnLCBjZG4gPSBUUlVFKQpgYGAKCmBgYHtyfQpodG1sdG9vbHM6OmluY2x1ZGVIVE1MKCJyTWFwcy5odG1sIikKYGBgCgojIFNFQ1RJT04gMjogU1RFTQojIFNMSURFIDk6IFN0ZW0gYW5kIG5vbi1zdGVtIGhpc3RvZ3JhbQpgYGB7ciBmaWcuaGVpZ2h0PTIuNiwgZmlnLndpZHRoPTIuM30KREFUQSAlPiUKICBncm91cF9ieSh5ZWFyLCBzdGVtKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4sIGZpbGwgPSBhcy5mYWN0b3Ioc3RlbSkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsCiAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayhyZXZlcnNlID0gRkFMU0UpLAogICAgICAgICAgIGFscGhhID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCIjMDBCMkU0IiwgIiMwRjJBNDgiKSwKICAgIG5hbWUgPSAiIiwKICAgIGxhYmVscyA9IGMoIm5vbi1TVEVNIiwgIlNURU0iKQogICkgKwogIGxhYnMoeSA9ICJcbiBOdW1iZXIiLCB4ID0gIlxuIFllYXIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gZnVuY3Rpb24oeCkgewogICAgICBwYXN0ZTAoeCAvIDEwMDAsICdLJykKICAgIH0KICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpCmBgYAoKCiMgU0xJREUgMTA6IFNURU0gYW5kIG5vbi1TVEVNIGJveHBsb3Q6ICJQcmV2YWlsaW5nIHdhZ2UgYm94cGxvdCB0aHJvdWdob3V0IHllYXJzIgpgYGB7cn0KREFUQSAlPiUKICBmaWx0ZXIocHJldmFpbGluZ193YWdlID49IDAgJiBwcmV2YWlsaW5nX3dhZ2UgPD0gNjAwMDAwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBhcy5mYWN0b3IoeWVhciksIHkgPSBwcmV2YWlsaW5nX3dhZ2UpKSArCiAgZ2VvbV9ib3hwbG90KAogICAgYWVzKGZpbGwgPSBhcy5mYWN0b3Ioc3RlbSkpLAogICAgb3V0bGllci5zaGFwZSA9IE5BLAogICAgYWxwaGEgPSAwLjksCiAgICBjb2xvciA9ICJ3aGl0ZSIKICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICJcbiBZZWFyIiwgeSA9ICJQcmV2YWlsaW5nIHdhZ2UgXG4iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gZnVuY3Rpb24oeCkgewogICAgICBwYXN0ZTAoeCAvIDEwMDAsICJLIikKICAgIH0KICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCIjMDBCMkU0IiwgIiMwRjJBNDgiKSwKICAgIG5hbWUgPSAiIiwKICAgIGxhYmVscyA9IGMoIm5vbi1TVEVNIiwgIlNURU0iKQogICkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgdmFsdWVzID0gYygiIzAwQjJFNCIsICIjMEYyQTQ4IiksCiAgICBuYW1lID0gIiIsCiAgICBsYWJlbHMgPSBjKCJub24tU1RFTSIsICJTVEVNIikKICApICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoNDAwMDAsIDEwMDAwMCkpCmBgYAoKCiMgU0xJREUgMTE6IFN0ZW0gYW5kIG5vbi1zdGVtIHByZXZhaWxpbmcgd2FnZSBkaXN0cmlidXRpb24gaW4gMjAxOApgYGB7cn0KREFUQSAlPiUKICBmaWx0ZXIoeWVhciA9PSAyMDE4KSAlPiUKICBmaWx0ZXIocHJldmFpbGluZ193YWdlID49IDAgJiBwcmV2YWlsaW5nX3dhZ2UgPD0gNDAwMDAwKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgeCA9IHByZXZhaWxpbmdfd2FnZSwKICAgIGNvbG9yID0gYXMuZmFjdG9yKHN0ZW0pLAogICAgZmlsbCA9IGFzLmZhY3RvcihzdGVtKQogICkpICsKICBnZW9tX2RlbnNpdHkoYWRqdXN0ID0gMiwgYWxwaGEgPSAwLjcpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGxhYnMoeCA9ICJcbiBQcmV2YWlsaW5nIHdhZ2UgKCQpIiwKICAgICAgIHkgPSBleHByZXNzaW9uKERlbnNpdHkgfiAoMTAgXiB7CiAgICAgICAgIC0zCiAgICAgICB9KSksCiAgICAgICB0aXRsZSA9ICIiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKAogICAgbGFiZWxzID0gZnVuY3Rpb24oeCkgewogICAgICBwYXN0ZTAoeCAvIDEwMDAsICdLJykKICAgIH0KICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBsYWJlbHMgPSBmdW5jdGlvbih4KSB7CiAgICAgIHBhc3RlMCh4ICogMTAwMCwgIiIpCiAgICB9CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gYygiIzAwQjJFNCIsICIjMEYyQTQ4IiksCiAgICBuYW1lID0gIiIsCiAgICBsYWJlbHMgPSBjKCJub24tU1RFTSIsICJTVEVNIikKICApICsKICBzY2FsZV9maWxsX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoIiMwMEIyRTQiLCAiIzBGMkE0OCIpLAogICAgbmFtZSA9ICIiLAogICAgbGFiZWxzID0gYygibm9uLVNURU0iLCAiU1RFTSIpCiAgKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgoKIyBTTElERSAxMiBBTkQgMTM6IGJhciBwbG90OiBzdGVtIGpvYnMKYGBge3J9CmR0IDwtIERBVEEgJT4lCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiYnVzaW5lc3MiKSAmCiAgICAgICgKICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImFuYWx5c3QiKSB8CiAgICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImludGVsbGlnZW5jZSIpCiAgICAgICkgLAogICAgImJ1c2luZXNzIGFuYWx5c3QiLAogICAgam9iX3RpdGxlCiAgKSkgJT4lCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiZGF0YSIpICYKICAgICAgKAogICAgICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiZW5naW5lZXIiKSB8CiAgICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgIndhcmVob3VzZSIpCiAgICAgICksCiAgICAiZGF0YSBlbmdpbmVlciIsCiAgICBqb2JfdGl0bGUKICApKSAlPiUKICBtdXRhdGUoam9iX3RpdGxlID0gaWZlbHNlKAogICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJkYXRhIikgJgogICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgInNjaWVudGlzdCIpLAogICAgImRhdGEgc2NpZW50aXN0IiwKICAgIGpvYl90aXRsZQogICkpICU+JQogIG11dGF0ZShqb2JfdGl0bGUgPSBpZmVsc2UoCiAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImRhdGEiKSAmCiAgICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiYW5hbHlzdHxhbmFseXRpY3MiKSwKICAgICJkYXRhIGFuYWx5c3QiLAogICAgam9iX3RpdGxlCiAgKSkgJT4lCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAibWFjaGluZXxkZWVwIikgJgogICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImxlYXJuaW5nIiksCiAgICAiZGVlcCBsZWFybmluZyAmIG1hY2hpbmUgbGVhcm5pbmciLAogICAgam9iX3RpdGxlCiAgKSkgJT4lCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAicHJvZHVjdCIpICYKICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJhbmFseXN0fGVuZ2luZWVyfGRhdGEiKSwKICAgICJkYXRhIHByb2R1Y3QgYW5hbHlzdCIsCiAgICBqb2JfdGl0bGUKICApKSAlPiUKICBtdXRhdGUoam9iX3RpdGxlID0gaWZlbHNlKAogICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJzZW5pb3Igc3lzdGVtcyBhbmFseXN0IGpjNjAiKSwKICAgICJzZW5pb3Igc3lzdGVtcyBhbmFseXN0IiwKICAgIGpvYl90aXRsZQogICkpICU+JQogIGZpbHRlcihzdGVtID09IDEpCgpkdCAlPiUKICBmaWx0ZXIoeWVhciA9PSAyMDE4KSAlPiUKICBncm91cF9ieShqb2JfdGl0bGUpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBhcnJhbmdlKC1uKSAlPiUKICBzbGljZSgxOjIwKSAlPiUKICBtdXRhdGUoY2F0ID0gaWZlbHNlKHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiYW5hbHlzdHxkYXRhIiksICJkYXRhIiwgIm5vbi1kYXRhIikpICU+JQogIGFycmFuZ2UobikgJT4lCiAgZ2diYXJwbG90KAogICAgImpvYl90aXRsZSIsCiAgICAibiIsCiAgICBmaWxsID0gImNhdCIsCiAgICBwYWxldHRlID0gYygiI0ZDMjk2NyIsICIjMDBCMkU0IiksCiAgICBhbHBoYSA9IDAuOCwKICAgIG9yaWVudGF0aW9uID0gImhvcml6IiwKICAgIGNvbG9yID0gIndoaXRlIgogICkgKwogIGxhYnMoeSA9ICJOdW1iZXIgb2YgQXBsaWNhdGlvbnMiLCB4ID0gIkpvYiBUaXRsZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgoKIyBvcmlnaW5hbApkdCAlPiUKICBmaWx0ZXIoeWVhciA9PSAyMDE4KSAlPiUKICBncm91cF9ieShqb2JfdGl0bGUpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBhcnJhbmdlKC1uKSAlPiUKICBzbGljZSgxOjIwKSAlPiUKICBtdXRhdGUoY2F0ID0gaWZlbHNlKHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiYW5hbHlzdHxkYXRhIiksICJkYXRhIiwgIm5vbi1kYXRhIikpICU+JQogIGFycmFuZ2UobikgJT4lCiAgZ2diYXJwbG90KAogICAgImpvYl90aXRsZSIsCiAgICAibiIsCiAgICBmaWxsID0gIiMwMEIyRTQiLAogICAgYWxwaGEgPSAwLjgsCiAgICBvcmllbnRhdGlvbiA9ICJob3JpeiIsCiAgICBjb2xvciA9ICJ3aGl0ZSIKICApICsKICBsYWJzKHkgPSAiTnVtYmVyIG9mIEFwbGljYXRpb25zIiwgeCA9ICJKb2IgVGl0bGVzIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMgU2xpZGUgMTUKYGBge3IsZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0KZHQgPC0gREFUQSAlPiUKICBmaWx0ZXIoCiAgICBkYXRhX2pvYl90aXRsZSAlaW4lIGMoCiAgICAgICJCdXNpbmVzcyBBbmFseXN0IiwKICAgICAgIkRhdGEgRW5naW5lZXIiLAogICAgICAiRGF0YSBBbmFseXN0IiwKICAgICAgIkRhdGEgU2NpZW50aXN0IgogICAgKQogICkgJT4lCiAgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUsIHllYXIpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBhcnJhbmdlKC1uKQoKcDEgPC0gZHQgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikrCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IGRhdGFfam9iX3RpdGxlKSwgc2l6ZSA9IDEuMikgKwogIGxhYnMoCiAgICB5ID0gIiIsCiAgICB4ID0gIlllYXIiLAogICAgdGl0bGUgPSAiQXBwbGljYXRpb25zIERhdGEgcmVsYXRlZCBqb2JzIiwKICAgIGZhY2UgPSAiYm9sZCIsCiAgICBzaXplID0gMTQKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0ZDMjk2NyIsICIjNDY1ODgxIiwgIiMwMDkwOWUiLCAiIzAwQjJFNCIpLAogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIiIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpCiAgKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCnAxCmBgYAoKIyBzbGlkZSAxNgoKYGBge3J9CmZpbHRlcmVkX2pvYiA8LSBEQVRBICU+JQogIGZpbHRlcigKICAgIGRhdGFfam9iX3RpdGxlICVpbiUgYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIsCiAgICAgICJEYXRhIEFuYWx5c3QiCiAgICApCiAgKQoKCmZpbHRlcmVkX2pvYiRkYXRhX2pvYl90aXRsZSA8LQogIGZhY3RvcigKICAgIGZpbHRlcmVkX2pvYiRkYXRhX2pvYl90aXRsZSwKICAgIGxldmVscyA9IGMoCiAgICAgICJEYXRhIEFuYWx5c3QiLAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIsCiAgICAgICJEYXRhIEVuZ2luZWVyIiwKICAgICAgIkRhdGEgU2NpZW50aXN0IgogICAgKSwKICAgIG9yZGVyZWQgPSBUUlVFCiAgKQoKCmZpbHRlcmVkX2pvYiAlPiUgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUpICU+JSBzdW1tYXJpc2UobWVhbiA9IG1lYW4ocHJldmFpbGluZ193YWdlKSkKZmlsdGVyZWRfam9iICU+JQogIGdncGxvdChhZXMoeSA9IHByZXZhaWxpbmdfd2FnZSwgeCA9IGRhdGFfam9iX3RpdGxlKSkgKwogIGdlb21fYm94cGxvdCgKICAgIGZpbGwgPSAiIzAwQjJFNCIsCiAgICBvdXRsaWVyLnNoYXBlID0gTkEsCiAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICB3aWR0aCA9IDAuNQogICkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYyg1MDAwMCwgMTIwMDAwKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh4ID0gIlxuIEpvYiB0aXRsZSIsIHkgPSAiUHJldmFpbGluZyB3YWdlIChwZXIgeWVhcikgXG4iLCB0aXRsZSA9ICJQcmV2YWlsaW5nIHdhZ2VzIGluIGRhdGEgcmVsYXRlZCBqb2JzIikgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMSksCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKQogICkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCgojIFNsaWRlIDE3CmBgYHtyfQp0b3BfY29tIDwtIERBVEEgJT4lCiAgZmlsdGVyKAogICAgZGF0YV9qb2JfdGl0bGUgJWluJSBjKAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIsCiAgICAgICJEYXRhIEFuYWx5c3QiLAogICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIKICAgICkKICApICU+JQogIGdyb3VwX2J5KGVtcGxveWVyX25hbWUpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBhcnJhbmdlKC1uKSAlPiUKICBzbGljZSgxOjIwKSAlPiUKICB1bmdyb3VwKCkKCnRvcF9jb20gPC0gdG9wX2NvbSRlbXBsb3llcl9uYW1lCgpzcGFfZGF0YSA8LSBEQVRBICU+JQogIGZpbHRlcihlbXBsb3llcl9uYW1lICVpbiUgdG9wX2NvbSkgJT4lCiAgZmlsdGVyKGVtcGxveWVyX25hbWUgIT0gImNhcGdlbWluaSBhbWVyaWNhIGluYyIpICU+JQogIGZpbHRlcigKICAgIGRhdGFfam9iX3RpdGxlICVpbiUgYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAiRGF0YSBBbmFseXN0IiwKICAgICAgIkRhdGEgRW5naW5lZXIiLAogICAgICAiRGF0YSBTY2llbnRpc3QiCiAgICApCiAgKSAlPiUKICBncm91cF9ieShlbXBsb3llcl9uYW1lLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkKCmNvbiA9IGMoImluZm9zeXMgbGltaXRlZCIsCiAgICAgICAgImRlbG9pdHRlIGNvbnN1bHRpbmcgbGxwIiwKICAgICAgICAiYW1hem9uIiwKICAgICAgICAiZmFjZWJvb2siLAogICAgICAgICJpYm0iKQpteUNvbG9yIDwtIGMoIiM0NjU4ODEiLCAiI0ZGQjZDMSIsICIjMDA5MDllIiwgIiMwMEIyRTQiLCAiI0ZDMjk2NyIpCgojIGMoYW1hem9uLCAiZGVsb2l0dGUiLCAiI2ZhY2Vib29rIiwgImlibSIsICJpbmZvIikKCmdncGxvdChzcGFfZGF0YSwgYWVzKHggPSB5ZWFyLCB5ID0gbiwgZ3JvdXAgPSBlbXBsb3llcl9uYW1lKSkgKwogIGdlb21fbGluZShhbHBoYSA9IDAuMywKICAgICAgICAgICAgc2l6ZSA9IDAuMikgKwogIGxhYnMoeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiTnVtYmVyIiwKICAgICAgIGNvbCA9ICIiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZW9tX2xpbmUoCiAgICBkYXRhID0gc3Vic2V0KHNwYV9kYXRhLCBlbXBsb3llcl9uYW1lICVpbiUgY29uKSwKICAgIGFlcyhjb2wgPSBlbXBsb3llcl9uYW1lKSwKICAgIHNpemUgPSAxLjIKICApICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gbXlDb2xvciwKICAgIGJyZWFrcyA9IGMoCiAgICAgICJpbmZvc3lzIGxpbWl0ZWQiLAogICAgICAiZGVsb2l0dGUgY29uc3VsdGluZyBsbHAiLAogICAgICAiYW1hem9uIiwKICAgICAgImZhY2Vib29rIiwKICAgICAgImlibSIKICAgICksCiAgICBsYWJlbHMgPSBjKAogICAgICAiSW5mb3N5cyBMaW1pdGVkIiwKICAgICAgIkRlbG9pdHRlIENvbnN1bHRpbmciLAogICAgICAiQW1hem9uIiwKICAgICAgIkZhY2Vib29rIiwKICAgICAgIklCTSIKICAgICkKICApICArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKYGBgCgoKIyBTbGlkZSAxNwojIFRvcCBUZWNoIENvbXBhbmllcyBhbmQgVGhlaXIgVHJlbmRzCmBgYHtyfQpzb2NfdG9wX3RlY2ggPC0gYygiQXBwbGUiLAogICAgICAgICAgICAgICAgICAiTWljcm9zb2Z0IiwKICAgICAgICAgICAgICAgICAgIkFtYXpvbiIsCiAgICAgICAgICAgICAgICAgICJGYWNlYm9vayIsCiAgICAgICAgICAgICAgICAgICJHb29nbGUiLAogICAgICAgICAgICAgICAgICAiSUJNIikKCgpEQVRBICU+JQogIGZpbHRlcigKICAgIGRhdGFfam9iX3RpdGxlICVpbiUgYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICJEYXRhIEFuYWx5c3QiLAogICAgICAiRGF0YSBTY2llbnRpc3QiCiAgICApCiAgKSAlPiUKICBtdXRhdGUoZW1wbG95ZXJfbmFtZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgJ2FwcGxlJyksCiAgICAnQXBwbGUnLAogICAgaWZlbHNlKAogICAgICBzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdtaWNyb3NvZnQnKSwKICAgICAgJ01pY3Jvc29mdCcsCiAgICAgIGlmZWxzZSgKICAgICAgICBzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdhbWF6b24nKSwKICAgICAgICAnQW1hem9uJywKICAgICAgICBpZmVsc2UoCiAgICAgICAgICBzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdmYWNlYm9vaycpLAogICAgICAgICAgJ0ZhY2Vib29rJywKICAgICAgICAgIGlmZWxzZSgKICAgICAgICAgICAgc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnZ29vZ2xlJyksCiAgICAgICAgICAgICdHb29nbGUnLAogICAgICAgICAgICBpZmVsc2Uoc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnaWJtJyksICdJQk0nLCAnbm8nKQogICAgICAgICAgKQogICAgICAgICkKICAgICAgKQogICAgKQogICkpICU+JQogIGdyb3VwX2J5KGVtcGxveWVyX25hbWUsIHllYXIpICU+JQogIHN1bW1hcmlzZSh0b3QgPSBuKCkpICU+JQogIGZpbHRlcighZW1wbG95ZXJfbmFtZSAlaW4lIGMoIm5vIiwgTkEpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZ2dwbG90KCkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlJkQnUiKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geWVhciwgeSA9IHRvdCwgY29sb3IgPSBlbXBsb3llcl9uYW1lKSwgc2l6ZSA9IDEuNSkgKwogIGxhYnMoeSA9ICJOdW1iZXIgb2YgQXBwbGljYXRpb25zIiwgeCA9ICJZZWFyIiwgY29sb3IgPSAiRW1wbG95ZXIiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpgYGAKCgojIERhdGEgam9icyBpbiB0b3AgY29tcGFuaWVzIApgYGB7cn0KZmlsdGVyZWRfam9iX2FsbCA8LSBEQVRBICU+JQogIGZpbHRlcigKICAgIGRhdGFfam9iX3RpdGxlICVpbiUgYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAiRGF0YSBBbmFseXN0IiwKICAgICAgIkRhdGEgRW5naW5lZXIiLAogICAgICAiRGF0YSBTY2llbnRpc3QiCiAgICApCiAgKSAlPiUKICBtdXRhdGUoZW1wbG95ZXJfbmFtZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgJ2FwcGxlJyksCiAgICAnQXBwbGUnLAogICAgaWZlbHNlKAogICAgICBzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdtaWNyb3NvZnQnKSwKICAgICAgJ01pY3Jvc29mdCcsCiAgICAgIGlmZWxzZSgKICAgICAgICBzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdhbWF6b24nKSwKICAgICAgICAnQW1hem9uJywKICAgICAgICBpZmVsc2UoCiAgICAgICAgICBzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdmYWNlYm9vaycpLAogICAgICAgICAgJ0ZhY2Vib29rJywKICAgICAgICAgIGlmZWxzZSgKICAgICAgICAgICAgc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnZ29vZ2xlJyksCiAgICAgICAgICAgICdHb29nbGUnLAogICAgICAgICAgICBpZmVsc2Uoc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnaWJtJyksICdJQk0nLCBlbXBsb3llcl9uYW1lKQogICAgICAgICAgKQogICAgICAgICkKICAgICAgKQogICAgKQogICkpIAogIApgYGAKCiNJQk0KCgoKYGBge3J9CnRvcF9jb20gPC0gREFUQSAlPiUKICBmaWx0ZXIoCiAgICBkYXRhX2pvYl90aXRsZSAlaW4lIGMoCiAgICAgICJCdXNpbmVzcyBBbmFseXN0IiwKICAgICAgIkRhdGEgQW5hbHlzdCIsCiAgICAgICJEYXRhIEVuZ2luZWVyIiwKICAgICAgIkRhdGEgU2NpZW50aXN0IgogICAgKQogICkgJT4lCiAgZ3JvdXBfYnkoZW1wbG95ZXJfbmFtZSkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQogIGFycmFuZ2UoLW4pICU+JQogIHNsaWNlKDE6MjApICU+JQogIHVuZ3JvdXAoKQoKdG9wX2NvbSA8LSB0b3BfY29tJGVtcGxveWVyX25hbWUKCmlibV9kYXRhIDwtIERBVEEgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgImlibSIpKSAlPiUKICBncm91cF9ieShqb2JfdGl0bGUsIHllYXIpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBtdXRhdGUoZGF0YV9qb2JfdGl0bGUgPQogICAgICAgICAgIGlmZWxzZSgKICAgICAgICAgICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiYnVzaW5lc3MiKSAmCiAgICAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImFuYWx5c3QiKSB8CiAgICAgICAgICAgICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImludGVsbGlnZW5jZSIpCiAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAiQnVzaW5lc3MgQW5hbHlzdCIsCiAgICAgICAgICAgICBOQQogICAgICAgICAgICkpICU+JQogIG11dGF0ZShkYXRhX2pvYl90aXRsZSA9CiAgICAgICAgICAgaWZlbHNlKAogICAgICAgICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJkYXRhIikgJgogICAgICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJlbmdpbmVlciIpIHwKICAgICAgICAgICAgICAgICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAid2FyZWhvdXNlIikKICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICJEYXRhIEVuZ2luZWVyIiwKICAgICAgICAgICAgIGRhdGFfam9iX3RpdGxlCiAgICAgICAgICAgKSkgJT4lCiAgbXV0YXRlKGRhdGFfam9iX3RpdGxlID0KICAgICAgICAgICBpZmVsc2UoCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImRhdGEiKSAmIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAic2NpZW50aXN0IiksCiAgICAgICAgICAgICAiRGF0YSBTY2llbnRpc3QiLAogICAgICAgICAgICAgZGF0YV9qb2JfdGl0bGUKICAgICAgICAgICApKSAlPiUKICBtdXRhdGUoZGF0YV9qb2JfdGl0bGUgPQogICAgICAgICAgIGlmZWxzZSgKICAgICAgICAgICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiZGF0YSIpICYKICAgICAgICAgICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJhbmFseXN0fGFuYWx5dGljcyIpLAogICAgICAgICAgICAgIkRhdGEgQW5hbHlzdCIsCiAgICAgICAgICAgICBkYXRhX2pvYl90aXRsZQogICAgICAgICAgICkpICU+JQogIG11dGF0ZShkYXRhX2pvYl90aXRsZSA9CiAgICAgICAgICAgaWZlbHNlKAogICAgICAgICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJtYWNoaW5lfGRlZXAiKSAmCiAgICAgICAgICAgICAgIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAibGVhcm5pbmciKSwKICAgICAgICAgICAgICJEYXRhIFNjaWVudGlzdCIsCiAgICAgICAgICAgICBkYXRhX2pvYl90aXRsZQogICAgICAgICAgICkpICU+JQogIG11dGF0ZShkYXRhX2pvYl90aXRsZSA9CiAgICAgICAgICAgaWZlbHNlKAogICAgICAgICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJwcm9kdWN0IikgJgogICAgICAgICAgICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImFuYWx5c3R8ZW5naW5lZXJ8ZGF0YSIpLAogICAgICAgICAgICAgIkRhdGEgQW5hbHlzdCIsCiAgICAgICAgICAgICBkYXRhX2pvYl90aXRsZQogICAgICAgICAgICkpICU+JQogIG11dGF0ZShkYXRhX2pvYl90aXRsZSA9CiAgICAgICAgICAgaWZlbHNlKAogICAgICAgICAgICAgc3RyX2RldGVjdChqb2JfdGl0bGUsICJwcm9kdWN0IikgJiBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgIm1hbmFnZXIiKSwKICAgICAgICAgICAgICJQcm9kdWN0IE1hbmFnZXIiLAogICAgICAgICAgICAgZGF0YV9qb2JfdGl0bGUKICAgICAgICAgICApKQoKY29uID0gYygiaW5mb3N5cyBsaW1pdGVkIiwKICAgICAgICAiZGVsb2l0dGUgY29uc3VsdGluZyBsbHAiLAogICAgICAgICJhbWF6b24iLAogICAgICAgICJmYWNlYm9vayIsCiAgICAgICAgImlibSIpCm15Q29sb3IgPC0gYygiIzQ2NTg4MSIsICIjRkZCNkMxIiwgIiMwMDkwOWUiLCAiIzAwQjJFNCIsICIjRkMyOTY3IikKCiMgYyhhbWF6b24sICJkZWxvaXR0ZSIsICIjZmFjZWJvb2siLCAiaWJtIiwgImluZm8iKQoKZ2dwbG90KGlibV9kYXRhLCBhZXMoeCA9IHllYXIsIHkgPSBuLCBncm91cCA9IGpvYl90aXRsZSkpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAwLjMsCiAgICAgICAgICAgIHNpemUgPSAwLjIpICsKICBsYWJzKHggPSAiWWVhciIsCiAgICAgICB5ID0gIk51bWJlciIsCiAgICAgICBjb2wgPSAiIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgZ2VvbV9saW5lKAogICAgZGF0YSA9IHN1YnNldCgKICAgICAgaWJtX2RhdGEsCiAgICAgIGRhdGFfam9iX3RpdGxlICVpbiUgYygKICAgICAgICAiQnVzaW5lc3MgQW5hbHlzdCIsCiAgICAgICAgIkRhdGEgQW5hbHlzdCIsCiAgICAgICAgIkRhdGEgRW5naW5lZXIiLAogICAgICAgICJEYXRhIFNjaWVudGlzdCIKICAgICAgKQogICAgKSwKICAgIGFlcyhjb2wgPSBkYXRhX2pvYl90aXRsZSksCiAgICBzaXplID0gMS4yCiAgKSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjRkMyOTY3IiwgIiM0NjU4ODEiLCAiIzAwOTA5ZSIsICIjMDBCMkU0IiksCiAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiIikgKwogIHlsaW0oMCwgMTUwKQpgYGAKCgoKCgpgYGB7cn0KZmlsdGVyZWRfam9iX2FsbCAlPiUKICBmaWx0ZXIoZW1wbG95ZXJfbmFtZSA9PSAnSUJNJykgJT4lCiAgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUsIHllYXIpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gbikpICsKICAjZ2VvbV9wb2ludChhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAyKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IGRhdGFfam9iX3RpdGxlKSwgc2l6ZSA9IDEuMikgKwogIGxhYnMoCiAgICB5ID0gIiIsCiAgICB4ID0gIlllYXIiLAogICAgdGl0bGUgPSAiIiwKICAgIGZhY2UgPSAiYm9sZCIsCiAgICBzaXplID0gMTQKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0ZDMjk2NyIsICIjNDY1ODgxIiwgIiMwMDkwOWUiLCAiIzAwQjJFNCIpLAogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIiIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpCiAgKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgoKYGBgCgojIEluZm9zeXMKYGBge3J9CgpmaWx0ZXJlZF9qb2JfYWxsICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdpbmZvc3lzJykpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAxLjIpICsKICBsYWJzKAogICAgeSA9ICIiLAogICAgeCA9ICJZZWFyIiwKICAgIHRpdGxlID0gIiIsCiAgICBmYWNlID0gImJvbGQiLAogICAgc2l6ZSA9IDE0CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNGQzI5NjciLCAiIzQ2NTg4MSIsICIjMDA5MDllIiwgIiMwMEIyRTQiKSwKICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICIiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKYGBgCgojIEFjY2VudHVyZQpgYGB7cn0KZmlsdGVyZWRfam9iX2FsbCAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnYWNjZW50dXJlJykpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAxLjIpICsKICBsYWJzKAogICAgeSA9ICIiLAogICAgeCA9ICJZZWFyIiwKICAgIHRpdGxlID0gIiIsCiAgICBmYWNlID0gImJvbGQiLAogICAgc2l6ZSA9IDE0CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNGQzI5NjciLCAiIzQ2NTg4MSIsICIjMDA5MDllIiwgIiMwMEIyRTQiKSwKICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICIiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KQogICkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKYGBgCgojIE1pY3Jvc29mdApgYGB7cn0KZmlsdGVyZWRfam9iX2FsbCAlPiUKICBmaWx0ZXIoZW1wbG95ZXJfbmFtZSA9PSAnTWljcm9zb2Z0JykgJT4lCiAgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUsIHllYXIpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gbikpICsKICAjZ2VvbV9wb2ludChhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAyKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IGRhdGFfam9iX3RpdGxlKSwgc2l6ZSA9IDEuMikgKwogIGxhYnMoCiAgICB5ID0gIiIsCiAgICB4ID0gIlllYXIiLAogICAgdGl0bGUgPSAiIiwKICAgIGZhY2UgPSAiYm9sZCIsCiAgICBzaXplID0gMTQKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0ZDMjk2NyIsICIjNDY1ODgxIiwgIiMwMDkwOWUiLCAiIzAwQjJFNCIpLAogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIiIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpCiAgKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyBBbWF6b24KYGBge3J9CmZpbHRlcmVkX2pvYl9hbGwgJT4lCiAgZmlsdGVyKGVtcGxveWVyX25hbWUgPT0gJ0FtYXpvbicpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAxLjIpICsKICBsYWJzKAogICAgeSA9ICIiLAogICAgeCA9ICJZZWFyIiwKICAgIHRpdGxlID0gIiIsCiAgICBmYWNlID0gImJvbGQiLAogICAgc2l6ZSA9IDE0CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNGQzI5NjciLCAiIzQ2NTg4MSIsICIjMDA5MDllIiwgIiMwMEIyRTQiKSwKICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICIiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KQogICkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCiMgRGVsb2l0dGUKYGBge3J9CmZpbHRlcmVkX2pvYl9hbGwgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgImRlbG9pdHRlIikpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAxLjIpICsKICBsYWJzKAogICAgeSA9ICIiLAogICAgeCA9ICJZZWFyIiwKICAgIHRpdGxlID0gIiIsCiAgICBmYWNlID0gImJvbGQiLAogICAgc2l6ZSA9IDE0CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNGQzI5NjciLCAiIzQ2NTg4MSIsICIjMDA5MDllIiwgIiMwMEIyRTQiKSwKICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICIiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KQogICkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCiMgRmFjZWJvb2sKYGBge3J9CmZpbHRlcmVkX2pvYl9hbGwgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgIkZhY2Vib29rIikpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAxLjIpICsKICBsYWJzKAogICAgeSA9ICIiLAogICAgeCA9ICJZZWFyIiwKICAgIHRpdGxlID0gIiIsCiAgICBmYWNlID0gImJvbGQiLAogICAgc2l6ZSA9IDE0CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNGQzI5NjciLCAiIzQ2NTg4MSIsICIjMDA5MDllIiwgIiMwMEIyRTQiKSwKICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICIiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KQogICkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCiMgQXBwbGUKYGBge3J9CmZpbHRlcmVkX2pvYl9hbGwgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgIkFwcGxlIikpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IG4pKSArCiAgI2dlb21fcG9pbnQoYWVzKGNvbG9yID0gZGF0YV9qb2JfdGl0bGUpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAxLjIpICsKICBsYWJzKAogICAgeSA9ICIiLAogICAgeCA9ICJZZWFyIiwKICAgIHRpdGxlID0gIiIsCiAgICBmYWNlID0gImJvbGQiLAogICAgc2l6ZSA9IDE0CiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNGQzI5NjciLCAiIzQ2NTg4MSIsICIjMDA5MDllIiwgIiMwMEIyRTQiKSwKICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICIiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KQogICkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCiMgR29vZ2xlCmBgYHtyfQpmaWx0ZXJlZF9qb2JfYWxsICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICJHb29nbGUiKSkgJT4lCiAgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUsIHllYXIpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gbikpICsKICAjZ2VvbV9wb2ludChhZXMoY29sb3IgPSBkYXRhX2pvYl90aXRsZSksIHNpemUgPSAyKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IGRhdGFfam9iX3RpdGxlKSwgc2l6ZSA9IDEuMikgKwogIGxhYnMoCiAgICB5ID0gIiIsCiAgICB4ID0gIlllYXIiLAogICAgdGl0bGUgPSAiIiwKICAgIGZhY2UgPSAiYm9sZCIsCiAgICBzaXplID0gMTQKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0ZDMjk2NyIsICIjNDY1ODgxIiwgIiMwMDkwOWUiLCAiIzAwQjJFNCIpLAogICAgICAgICAgICAgICAgICAgICBuYW1lID0gIiIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpCiAgKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKIyMgRmFjZWJvb2sKCmBgYHtyfQpoMWJfZmFjZWJvb2sgPC0gaDFiX2RmICU+JQogIGZpbHRlcihlbXBsb3llcl9uYW1lID09ICdmYWNlYm9vaycpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgYXJyYW5nZSgtbikKICAKYGBgCgoKCmBgYHtyfQpjb24gPSBjKCJEYXRhIFNjaWVudGlzdCIsCiAgICAgICAgInNvZnR3YXJlIGVuZ2luZWVyIiwKICAgICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICAgJ3Jlc2VhcmNoIHNjaWVudGlzdCcpCmdncGxvdChoMWJfZmFjZWJvb2ssIGFlcyh4ID0geWVhciwgeSA9IG4sIGdyb3VwID0gZGF0YV9qb2JfdGl0bGUpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMC4zLAogICAgICAgICAgICBzaXplID0gMC4yKSArCiAgbGFicyh0aXRsZSA9ICJIMUIgaW4gRmFjZWJvb2siLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiTnVtYmVyIiwKICAgICAgIGNvbCA9ICdKb2IgVGl0bGUnKSArCiAgdGhlbWVfbGlnaHQoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICBnZW9tX2xpbmUoCiAgICBkYXRhID0gc3Vic2V0KGgxYl9mYWNlYm9vaywgZGF0YV9qb2JfdGl0bGUgJWluJSBjb24pLAogICAgYWVzKGNvbCA9IGRhdGFfam9iX3RpdGxlKSwKICAgIHNpemUgPSAwLjcKICApICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgZmFtaWx5ID0gIkhlbHZldGljYSIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFtaWx5ID0gIkhlbHZldGljYSIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkKICApICsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShsYWJlbHMgPSBjKAogICAgIkRhdGEgRW5naW5lZXIiLAogICAgIkRhdGEgU2NpZW50aXN0IiwKICAgICJSZXNlYXJjaCBTY2llbnRpc3QiLAogICAgIlNvZnR3YXJlIEVuZ2luZWVyIgogICkpCgpgYGAKCiMjIEFtYXpvbgoKYGBge3J9CmgxYl9hbWF6b24gPC0gaDFiX2RmICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KGVtcGxveWVyX25hbWUsICdhbWF6b24nKSkgJT4lCiAgdW5ncm91cChkYXRhX2pvYl90aXRsZSkgJT4lCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZSgKICAgIHN0cl9kZXRlY3QoZGF0YV9qb2JfdGl0bGUsICdzb2Z0d2FyZSBkZXZlbG9wbWVudCBlbmdpbmVlcicpLAogICAgJ3NvZnR3YXJlIGRldmVsb3BtZW50IGVuZ2luZWVyJywKICAgIGlmZWxzZSgKICAgICAgc3RyX2RldGVjdChkYXRhX2pvYl90aXRsZSwgJ3RlY2huaWNhbCBwcm9ncmFtIG1hbmFnZXInKSwKICAgICAgJ3RlY2huaWNhbCBwcm9ncmFtIG1hbmFnZXInLAogICAgICBkYXRhX2pvYl90aXRsZQogICAgKQogICkpICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgYXJyYW5nZSgtbikKCmBgYAoKYGBge3J9CmNvbiA9IGMoCiAgIkRhdGEgU2NpZW50aXN0IiwKICAic29mdHdhcmUgZGV2ZWxvcG1lbnQgZW5naW5lZXIiLAogICJidXNpbmVzcyBhbmFseXN0IiwKICAiRGF0YSBFbmdpbmVlciIsCiAgInRlY2huaWNhbCBwcm9ncmFtIG1hbmFnZXIiCikKZ2dwbG90KGgxYl9hbWF6b24sIGFlcyh4ID0geWVhciwgeSA9IG4sIGdyb3VwID0gZGF0YV9qb2JfdGl0bGUpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMC4zLAogICAgICAgICAgICBzaXplID0gMC4yKSArCiAgbGFicyh0aXRsZSA9ICJIMUIgaW4gQW1hem9uIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIk51bWJlciIsCiAgICAgICBjb2wgPSAnSm9iIFRpdGxlJykgKwogIHRoZW1lX2xpZ2h0KCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArCiAgZ2VvbV9saW5lKAogICAgZGF0YSA9IHN1YnNldChoMWJfYW1hem9uLCBkYXRhX2pvYl90aXRsZSAlaW4lIGNvbiksCiAgICBhZXMoY29sID0gZGF0YV9qb2JfdGl0bGUpLAogICAgc2l6ZSA9IDAuNwogICkgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgc2l6ZSA9IDE0LAogICAgICBmYW1pbHkgPSAiSGVsdmV0aWNhIiwKICAgICAgZmFjZSA9ICJib2xkIgogICAgKSwKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYW1pbHkgPSAiSGVsdmV0aWNhIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKQogICkgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKAogICAgbGFiZWxzID0gYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIsCiAgICAgICJTb2Z0d2FyZSBEZXZlbG9wbWVudCBFbmdpbmVlciIsCiAgICAgICJUZWNobmljYWwgUHJvZ3JhbSBNYW5hZ2VyIgogICAgKQogICkKYGBgCgoKIyMgTWljcm9zb2Z0CgpgYGB7cn0KaDFiX21pY3JvIDwtIGgxYl9kZiAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnbWljcm9zb2Z0JykpICU+JQogIHVuZ3JvdXAoZGF0YV9qb2JfdGl0bGUpICU+JQogIG11dGF0ZShqb2JfdGl0bGUgPSBpZmVsc2UoCiAgICBzdHJfZGV0ZWN0KAogICAgICBkYXRhX2pvYl90aXRsZSwKICAgICAgJ3NvZnR3YXJlIGVuZ2luZWVyfHNvZnR3YXJlIGRldmVsb3BtZW50IGVuZ2luZWVyJwogICAgKSwKICAgICdzb2Z0d2FyZSBlbmdpbmVlcicsCiAgICBpZmVsc2UoCiAgICAgIHN0cl9kZXRlY3QoZGF0YV9qb2JfdGl0bGUsICdwcm9ncmFtIG1hbmFnZXInKSwKICAgICAgJ3Byb2dyYW0gbWFuYWdlcicsCiAgICAgIGRhdGFfam9iX3RpdGxlCiAgICApCiAgKSkgJT4lCiAgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUsIHllYXIpICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICBhcnJhbmdlKC1uKQogIApgYGAKCmBgYHtyfQpjb24gPSBjKCJEYXRhIFNjaWVudGlzdCIsICJzb2Z0d2FyZSBlbmdpbmVlciIsICJwcm9ncmFtIG1hbmFnZXIiKQpnZ3Bsb3QoaDFiX21pY3JvLCBhZXMoeCA9IHllYXIsIHkgPSBuLCBncm91cCA9IGRhdGFfam9iX3RpdGxlKSkgKwogIGdlb21fbGluZShhbHBoYSA9IDAuMywKICAgICAgICAgICAgc2l6ZSA9IDAuMikgKwogIGxhYnModGl0bGUgPSAiSDFCIGluIE1pY3Jvc29mdCIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJOdW1iZXIiLAogICAgICAgY29sID0gJ0pvYiBUaXRsZScpICsKICB0aGVtZV9saWdodCgpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIGdlb21fbGluZSgKICAgIGRhdGEgPSBzdWJzZXQoaDFiX21pY3JvLCBkYXRhX2pvYl90aXRsZSAlaW4lIGNvbiksCiAgICBhZXMoY29sID0gZGF0YV9qb2JfdGl0bGUpLAogICAgc2l6ZSA9IDAuNwogICkgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgc2l6ZSA9IDE0LAogICAgICBmYW1pbHkgPSAiSGVsdmV0aWNhIiwKICAgICAgZmFjZSA9ICJib2xkIgogICAgKSwKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYW1pbHkgPSAiSGVsdmV0aWNhIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKQogICkgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGxhYmVscyA9IGMoIkRhdGEgU2NpZW50aXN0IiwgIlByb2dyYW0gTWFuYWdlciIsICJTb2Z0d2FyZSBFbmdpbmVlciIpKQpgYGAKCgojIyBHb29nbGUKCmBgYHtyfQpoMWJfZ29vZ2xlIDwtIGgxYl9kZiAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdChlbXBsb3llcl9uYW1lLCAnZ29vZ2xlJykpCgpgYGAKCmBgYHtyfQpoMWJfZ29vZ2xlIDwtIGgxYl9nb29nbGUgJT4lCiAgdW5ncm91cChqb2JfdGl0bGUpICU+JQogIG11dGF0ZShqb2JfdGl0bGUgPSBpZmVsc2UoCiAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgJ3NvZnR3YXJlIGVuZ2luZWVyJyksCiAgICAnc29mdHdhcmUgZW5naW5lZXInLAogICAgaWZlbHNlKAogICAgICBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgJ2hhcmR3YXJlIGVuZ2luZWVyJyksCiAgICAgICdoYXJkd2FyZSBlbmdpbmVlcicsCiAgICAgIGpvYl90aXRsZQogICAgKQogICkpICU+JQogIGdyb3VwX2J5KGpvYl90aXRsZSwgeWVhcikgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQogIGFycmFuZ2UoLW4pCmBgYAoKYGBge3J9CmNvbiA9IGMoCiAgIkRhdGEgU2NpZW50aXN0IiwKICAic29mdHdhcmUgZW5naW5lZXIiLAogICJwcm9ncmFtIG1hbmFnZXIiLAogICJwcm9kdWN0IG1hbmFnZXIiLAogICJidXNpbmVzcyBhbmFseXN0IgopCmdncGxvdChoMWJfZ29vZ2xlLCBhZXMoeCA9IHllYXIsIHkgPSBuLCBncm91cCA9IGpvYl90aXRsZSkpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAwLjMsCiAgICAgICAgICAgIHNpemUgPSAwLjIpICsKICBsYWJzKHRpdGxlID0gIkgxQiBpbiBHb29nbGUiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiTnVtYmVyIiwKICAgICAgIGNvbCA9ICdKb2IgVGl0bGUnKSArCiAgdGhlbWVfbGlnaHQoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICBnZW9tX2xpbmUoCiAgICBkYXRhID0gc3Vic2V0KGgxYl9nb29nbGUsIGpvYl90aXRsZSAlaW4lIGNvbiksCiAgICBhZXMoY29sID0gam9iX3RpdGxlKSwKICAgIHNpemUgPSAwLjcKICApICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgZmFtaWx5ID0gIkhlbHZldGljYSIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFtaWx5ID0gIkhlbHZldGljYSIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkKICApICsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZSgKICAgIGxhYmVscyA9IGMoCiAgICAgICJCdXNpbmVzcyBBbmFseXN0IiwKICAgICAgIkRhdGEgU2NpZW50aXN0IiwKICAgICAgIlByb2R1Y3QgTWFuYWdlciIsCiAgICAgICJQcm9ncmFtIE1hbmFnZXIiLAogICAgICAiU29mdHdhcmUgRW5naW5lZXIiCiAgICApCiAgKQpgYGAKCgojIyBJQk0gCgpgYGB7cn0KaDFiX2libSA8LSBoMWJfZGYgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgJ2libScpKQoKYGBgCgpgYGB7cn0KaDFiX2libSA8LSBoMWJfaWJtICU+JQogIGdyb3VwX2J5KGRhdGFfam9iX3RpdGxlLCB5ZWFyKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgYXJyYW5nZSgtbikKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD0yLjV9CmNvbiA9IGMoIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAgICJEYXRhIEVuZ2luZWVyIiwKICAgICAgICAiRGF0YSBTY2llbnRpc3QiLAogICAgICAgICJEYXRhIEFuYWx5c3QiKQpnZ3Bsb3QoaDFiX2libSwgYWVzKHggPSB5ZWFyLCB5ID0gbiwgZ3JvdXAgPSBkYXRhX2pvYl90aXRsZSkpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAwLjMsCiAgICAgICAgICAgIHNpemUgPSAwLjIpICsKICBsYWJzKHRpdGxlID0gIiIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJOdW1iZXIiLAogICAgICAgY29sID0gJ0pvYiBUaXRsZScpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArCiAgZ2VvbV9saW5lKAogICAgZGF0YSA9IHN1YnNldChoMWJfaWJtLCBkYXRhX2pvYl90aXRsZSAlaW4lIGNvbiksCiAgICBhZXMoY29sID0gZGF0YV9qb2JfdGl0bGUpLAogICAgc2l6ZSA9IDEuMQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjRkMyOTY3IiwgIiM0NjU4ODEiLCAiIzAwOTA5ZSIsICIjMDBCMkU0IiksCiAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiIikgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhbWlseSA9ICJIZWx2ZXRpY2EiKSwKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYW1pbHkgPSAiSGVsdmV0aWNhIiksCiAgICAjYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkIiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiCiAgKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAsIDEwMDApKQpgYGAKCiMjIFViZXIKCmBgYHtyfQpoMWJfdWJlciA8LSBoMWJfZGYgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoZW1wbG95ZXJfbmFtZSwgJ3ViZXInKSkgJT4lCiAgdW5ncm91cChkYXRhX2pvYl90aXRsZSkgJT4lCiAgbXV0YXRlKGRhdGFfam9iX3RpdGxlID0gaWZlbHNlKAogICAgc3RyX2RldGVjdChkYXRhX2pvYl90aXRsZSwgJ3NvZnR3YXJlIGVuZ2luZWVyJyksCiAgICAnU29mdHdhcmUgRW5naW5lZXInLAogICAgZGF0YV9qb2JfdGl0bGUKICApKSAlPiUKICBncm91cF9ieShkYXRhX2pvYl90aXRsZSwgeWVhcikgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQogIGFycmFuZ2UoLW4pCmBgYAoKYGBge3J9CmNvbiA9IGMoIlNvZnR3YXJlIEVuZ2luZWVyIiwgIkRhdGEgU2NpZW50aXN0IiwgIkRhdGEgQW5hbHlzdCIpCmdncGxvdChoMWJfdWJlciwgYWVzKHggPSB5ZWFyLCB5ID0gbiwgZ3JvdXAgPSBkYXRhX2pvYl90aXRsZSkpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAwLjMsCiAgICAgICAgICAgIHNpemUgPSAwLjIpICsKICBsYWJzKHRpdGxlID0gIkgxQiBpbiBVYmVyIiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIk51bWJlciIsCiAgICAgICBjb2wgPSAnSm9iIFRpdGxlJykgKwogIHRoZW1lX2xpZ2h0KCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArCiAgZ2VvbV9saW5lKAogICAgZGF0YSA9IHN1YnNldChoMWJfdWJlciwgZGF0YV9qb2JfdGl0bGUgJWluJSBjb24pLAogICAgYWVzKGNvbCA9IGRhdGFfam9iX3RpdGxlKSwKICAgIHNpemUgPSAwLjcKICApICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIHNpemUgPSAxNCwKICAgICAgZmFtaWx5ID0gIkhlbHZldGljYSIsCiAgICAgIGZhY2UgPSAiYm9sZCIKICAgICksCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFtaWx5ID0gIkhlbHZldGljYSIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSkKICApCmBgYAoKCiMgRGF0YSBqb2IgcGVyIHN0YXRlIGluIDIwMTgKCmBgYHtyfQpEQVRBX2NlcnRpZmljYXRlX2RhdGEgPC0gREFUQSAlPiUKICBmaWx0ZXIoY2FzZV9zdGF0dXMgPT0gImNlcnRpZmllZCIpICU+JQogIGZpbHRlcigKICAgIGRhdGFfam9iX3RpdGxlICVpbiUgYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiLAogICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICJEYXRhIEFuYWx5c3QiLAogICAgICAiRGF0YSBTY2llbnRpc3QiCiAgICApCiAgKSAlPiUKICBncm91cF9ieSh3b3Jrc2l0ZV9zdGF0ZV9hYmIsIHllYXIpICU+JQogIHN1bW1hcmlzZShudW0gPSBuKCkpCmBgYAoKYGBge3J9CkRBVEFfbmV3X2RhdGEgPC0gIERBVEFfY2VydGlmaWNhdGVfZGF0YSAlPiUKICB1bmdyb3VwKHdvcmtzaXRlX3N0YXRlX2FiYikgJT4lCiAgbXV0YXRlKHdvcmtzaXRlX3N0YXRlX2FiYiA9IHN0cl90b191cHBlcih3b3Jrc2l0ZV9zdGF0ZV9hYmIpKQpgYGAKCmBgYHtyfQpkMSA8LQogIGljaG9yb3BsZXRoKAogICAgbnVtIH4gd29ya3NpdGVfc3RhdGVfYWJiLAogICAgZGF0YSA9IERBVEFfbmV3X2RhdGEsCiAgICBhbmltYXRlID0gJ3llYXInLAogICAgbmN1dHMgPSA4LAogICAgbGVnZW5kID0gRkFMU0UsCiAgICBnZW9ncmFwaHlDb25maWcgPSBsaXN0KHBvcHVwVGVtcGxhdGUgPSAiIyFmdW5jdGlvbihnZW8sIGRhdGEpIHtyZXR1cm4gJzxkaXYgY2xhc3M9XCJob3ZlcmluZm9cIj48c3Ryb25nPicgKyBkYXRhLndvcmtzaXRlX3N0YXRlX2FiYiArICc8YnI+JyArIGRhdGEubnVtICsgJzwvc3Ryb25nPjwvZGl2Pic7fSEjIikKICApCmBgYAoKYGBge3J9CmQxJHNhdmUoJ3JNYXBzX2RhdGEuaHRtbCcsIGNkbiA9IFRSVUUpCmBgYAoKYGBge3J9Cmh0bWx0b29sczo6aW5jbHVkZUhUTUwoInJNYXBzLmh0bWwiKQpgYGAKCgojIyBBbGx1dmlhCmBgYHtyLGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTIuN30KZmlsdGVyZWRfam9iIDwtIERBVEEgJT4lCiAgZmlsdGVyKHllYXIgPT0gMjAxOCkgJT4lCiAgZmlsdGVyKAogICAgZGF0YV9qb2JfdGl0bGUgJWluJSBjKAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIsCiAgICAgICJEYXRhIEFuYWx5c3QiLAogICAgICAiRGF0YSBFbmdpbmVlciIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIKICAgICkKICApCgoKdG9wXzEwX3N0YXRlIDwtIGZpbHRlcmVkX2pvYiAlPiUKICBncm91cF9ieSh3b3Jrc2l0ZV9zdGF0ZV9hYmIpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgYXJyYW5nZShkZXNjKGNvdW50KSkgJT4lCiAgc2xpY2UoMToxMCkKCmZsb3dzIDwtIGZpbHRlcmVkX2pvYiAlPiUKICBmaWx0ZXIod29ya3NpdGVfc3RhdGVfYWJiICVpbiUgdG9wXzEwX3N0YXRlJHdvcmtzaXRlX3N0YXRlX2FiYikgJT4lCiAgZ3JvdXBfYnkoZGF0YV9qb2JfdGl0bGUsCiAgICAgICAgICAgd29ya3NpdGVfc3RhdGVfYWJiKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpCgoKZ2dwbG90KGZsb3dzLAogICAgICAgYWVzKHkgPSBjb3VudCwgYXhpczEgPSBkYXRhX2pvYl90aXRsZSwgYXhpczIgPSB3b3Jrc2l0ZV9zdGF0ZV9hYmIpKSArCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IGRhdGFfam9iX3RpdGxlKSkgKwogIGdlb21fc3RyYXR1bSgKICAgIHdpZHRoID0gMSAvIDgsCiAgICBmaWxsID0gIiMwRjJBNDgiLAogICAgY29sb3IgPSAiZ3JleSIsCiAgICBhbHBoYSA9IDAuOQogICkgKwogIGdlb21fbGFiZWwoc3RhdCA9ICJzdHJhdHVtIiwgbGFiZWwuc3RyYXRhID0gVFJVRSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0ZDMjk2NyIsICIjNDY1ODgxIiwgIiMwMDkwOWUiLCAiIzAwQjJFNCIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSBOVUxMKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb2IgdGl0bGUiLCAiU3RhdGUiKSwKICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYWNlID0gImJvbGQiKSkgKwogIHRoZW1lKGxpbmUgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKCiMjIGJhciBwbG90OnN0ZW0gcHJvZ3JhbSBpbiBkaWZmZXJlbnQgam9iIHRpdGxlcwpgYGB7cn0KREFUQSAlPiUgCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZShzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImJ1c2luZXNzIikmIChzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImFuYWx5c3QiKXxzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImludGVsbGlnZW5jZSIpKSAsICJidXNpbmVzcyBhbmFseXN0Iiwgam9iX3RpdGxlKSkgJT4lIAogIG11dGF0ZShqb2JfdGl0bGUgPSBpZmVsc2Uoc3RyX2RldGVjdChqb2JfdGl0bGUsICJkYXRhIikmIChzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImVuZ2luZWVyIil8c3RyX2RldGVjdChqb2JfdGl0bGUsICJ3YXJlaG91c2UiKSksICJkYXRhIGVuZ2luZWVyIiwgam9iX3RpdGxlKSkgJT4lIAogIG11dGF0ZShqb2JfdGl0bGUgPSBpZmVsc2Uoc3RyX2RldGVjdChqb2JfdGl0bGUsICJkYXRhIikmIHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAic2NpZW50aXN0IiksICJkYXRhIHNjaWVudGlzdCIsIGpvYl90aXRsZSkpICU+JSAKICBtdXRhdGUoam9iX3RpdGxlID0gaWZlbHNlKHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAiZGF0YSIpJiBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImFuYWx5c3R8YW5hbHl0aWNzIiksICJkYXRhIGFuYWx5c3QiLCBqb2JfdGl0bGUpKSAlPiUgCiAgbXV0YXRlKGpvYl90aXRsZSA9IGlmZWxzZShzdHJfZGV0ZWN0KGpvYl90aXRsZSwgIm1hY2hpbmV8ZGVlcCIpJiBzdHJfZGV0ZWN0KGpvYl90aXRsZSwgImxlYXJuaW5nIiksICJkZWVwIGxlYXJuaW5nICYgbWFjaGluZSBsZWFybmluZyIsIGpvYl90aXRsZSkpICU+JSAKICBtdXRhdGUoam9iX3RpdGxlID0gaWZlbHNlKHN0cl9kZXRlY3Qoam9iX3RpdGxlLCAicHJvZHVjdCIpICYgc3RyX2RldGVjdChqb2JfdGl0bGUsICJhbmFseXN0fGVuZ2luZWVyfGRhdGEiKSwgImRhdGEgcHJvZHVjdCBhbmFseXN0Iiwgam9iX3RpdGxlKSkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMTgpICU+JSAKICBmaWx0ZXIoc3RlbSA9PSAxKSAlPiUgCiAgZ3JvdXBfYnkoam9iX3RpdGxlKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JQogIGFycmFuZ2UoLW4pICU+JSAKICBzbGljZSgxOjIwKSAlPiUgCiAgZ2diYXJwbG90KCJqb2JfdGl0bGUiLCAibiIsIGZpbGwgPSAiIzAwQjJFNCIsIGNvbG9yID0gIndoaXRlIiwgYWxwaGEgPSAwLjgsIHNvcnQudmFsID0gImFzYyIsIG9yaWVudGF0aW9uID0gImhvcml6IikgJT4lIAogIGxhYnModGl0bGUgPSAic3RlbSBwcm9ncmFtIikKYGBgCgojIE1BUCAtIGRhdGEgam9iIHdpdGggdGhlIGhpZ2hlc3QgbnVtYmVyIGluIGVhY2ggY2l0eSAKYGBge3J9CmdncGxvdChwb2ludHMpICsKICBnZW9tX3NmKAogICAgZGF0YSA9IHN0YXRlX21hcHMsCiAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICBmaWxsID0gImxpZ2h0Z3JleSIsCiAgICBhbHBoYSA9IDAuNQogICkgKwogIGdlb21fcG9pbnQoYWVzKAogICAgeCA9IGppdHRlcihsb24sIDEwMCksCiAgICB5ID0gaml0dGVyKGxhdCwgMTAwKSwKICAgIGNvbG9yID0gbWF4X2pvYiwKICAgIHNpemUgPSBtYXgKICApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoCiAgICAgICJCdXNpbmVzcyBBbmFseXN0IiA9ICIjMDBCMkU0IiwKICAgICAgIkRhdGEgQW5hbHlzdCIgPSAiIzBGMkE0OCIsCiAgICAgICJEYXRhIEVuZ2luZWVyIiA9ICIjMDA4QjhCIiwKICAgICAgIkRhdGEgU2NpZW50aXN0IiA9ICIjRkMyOTY3IgogICAgKSwKICAgIG5hbWUgPSAiSm9iIFRpdGxlIgogICkgKwogIHRoZW1lKAogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIsCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAsIC0wLjEpLAogICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDApCiAgKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIiIsCiAgICAgICB0aXRsZSA9ICIiLAogICAgICAgc2l6ZSA9ICJOdW1iZXIiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QocG9pbnRzX2NhKSArCiAgZ2VvbV9zZigKICAgIGRhdGEgPSBzdGF0ZV9tYXBzX2NhLAogICAgY29sb3IgPSAid2hpdGUiLAogICAgZmlsbCA9ICJsaWdodGdyZXkiLAogICAgYWxwaGEgPSAwLjUKICApICsKICBnZW9tX3BvaW50KGFlcygKICAgIHggPSBqaXR0ZXIobG9uKSwKICAgIHkgPSBqaXR0ZXIobGF0KSwKICAgIGNvbG9yID0gbWF4X2pvYiwKICAgIHNpemUgPSBtYXgKICApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoCiAgICAgICJCdXNpbmVzcyBBbmFseXN0IiA9ICIjMDBCMkU0IiwKICAgICAgIkRhdGEgQW5hbHlzdCIgPSAiIzBGMkE0OCIsCiAgICAgICJEYXRhIEVuZ2luZWVyIiA9ICIjMDA4QjhCIiwKICAgICAgIkRhdGEgU2NpZW50aXN0IiA9ICIjRkMyOTY3IgogICAgKSwKICAgIG5hbWUgPSAiSm9iIFRpdGxlIgogICkgKwogIHRoZW1lKAogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICNsZWdlbmQucG9zaXRpb24gPSBjKDAsMCksIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLDApCiAgKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIiIsCiAgICAgICB0aXRsZSA9ICIiLAogICAgICAgc2l6ZSA9ICJOdW1iZXIiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QocG9pbnRzX3R4KSArCiAgZ2VvbV9zZigKICAgIGRhdGEgPSBzdGF0ZV9tYXBzX3R4LAogICAgY29sb3IgPSAid2hpdGUiLAogICAgZmlsbCA9ICJsaWdodGdyZXkiLAogICAgYWxwaGEgPSAwLjUKICApICsKICBnZW9tX3BvaW50KGFlcygKICAgIHggPSBqaXR0ZXIobG9uKSwKICAgIHkgPSBqaXR0ZXIobGF0KSwKICAgIGNvbG9yID0gbWF4X2pvYiwKICAgIHNpemUgPSBtYXgKICApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoCiAgICAgICJCdXNpbmVzcyBBbmFseXN0IiA9ICIjMDBCMkU0IiwKICAgICAgIkRhdGEgQW5hbHlzdCIgPSAiIzBGMkE0OCIsCiAgICAgICJEYXRhIEVuZ2luZWVyIiA9ICIjMDA4QjhCIiwKICAgICAgIkRhdGEgU2NpZW50aXN0IiA9ICIjRkMyOTY3IgogICAgKSwKICAgIG5hbWUgPSAiSm9iIFRpdGxlIgogICkgKwogIHRoZW1lKAogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICNsZWdlbmQucG9zaXRpb24gPSBjKDAsMCksIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLDApCiAgKSArCiAgbGFicyh4ID0gIiIsCiAgICAgICB5ID0gIiIsCiAgICAgICB0aXRsZSA9ICIiLAogICAgICAgc2l6ZSA9ICJOdW1iZXIiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QocG9pbnRzX25vcnRoZWFzdCkgKwogIGdlb21fc2YoCiAgICBkYXRhID0gc3RhdGVfbWFwc19ub3J0aGVhc3QsCiAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICBmaWxsID0gImxpZ2h0Z3JleSIsCiAgICBhbHBoYSA9IDAuNQogICkgKwogIGdlb21fcG9pbnQoYWVzKAogICAgeCA9IGppdHRlcihsb24pLAogICAgeSA9IGppdHRlcihsYXQpLAogICAgY29sb3IgPSBtYXhfam9iLAogICAgc2l6ZSA9IG1heAogICksIGFscGhhID0gMC41KSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gYygKICAgICAgIkJ1c2luZXNzIEFuYWx5c3QiID0gIiMwMEIyRTQiLAogICAgICAiRGF0YSBBbmFseXN0IiA9ICIjMEYyQTQ4IiwKICAgICAgIkRhdGEgRW5naW5lZXIiID0gIiMwMDhCOEIiLAogICAgICAiRGF0YSBTY2llbnRpc3QiID0gIiNGQzI5NjciCiAgICApLAogICAgbmFtZSA9ICJKb2IgVGl0bGUiCiAgKSArCiAgdGhlbWUoCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgI2xlZ2VuZC5wb3NpdGlvbiA9IGMoMCwwKSwgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsMCkKICApICsKICBsYWJzKHggPSAiIiwKICAgICAgIHkgPSAiIiwKICAgICAgIHRpdGxlID0gIiIsCiAgICAgICBzaXplID0gIk51bWJlciIpCmBgYAoKYGBge3J9CmdncGxvdChwb2ludHNfbWlkd2VzdCkgKwogIGdlb21fc2YoCiAgICBkYXRhID0gc3RhdGVfbWFwc19taWR3ZXN0LAogICAgY29sb3IgPSAid2hpdGUiLAogICAgZmlsbCA9ICJsaWdodGdyZXkiLAogICAgYWxwaGEgPSAwLjUKICApICsKICBnZW9tX3BvaW50KGFlcygKICAgIHggPSBqaXR0ZXIobG9uLCAxMDApLAogICAgeSA9IGppdHRlcihsYXQsIDEwMCksCiAgICBjb2xvciA9IG1heF9qb2IsCiAgICBzaXplID0gbWF4CiAgKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIgPSAiIzAwQjJFNCIsCiAgICAgICJEYXRhIEFuYWx5c3QiID0gIiMwRjJBNDgiLAogICAgICAiRGF0YSBFbmdpbmVlciIgPSAiIzAwOEI4QiIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIgPSAiI0ZDMjk2NyIKICAgICksCiAgICBuYW1lID0gIkpvYiBUaXRsZSIKICApICsKICB0aGVtZSgKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAjbGVnZW5kLnBvc2l0aW9uID0gYygwLDApLCBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwwKQogICkgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICIiLAogICAgICAgdGl0bGUgPSAiIiwKICAgICAgIHNpemUgPSAiTnVtYmVyIikKYGBgCgpgYGB7cn0KZ2dwbG90KHBvaW50c190bikgKwogIGdlb21fc2YoCiAgICBkYXRhID0gc3RhdGVfbWFwc190biwKICAgIGNvbG9yID0gIndoaXRlIiwKICAgIGZpbGwgPSAibGlnaHRncmV5IiwKICAgIGFscGhhID0gMC41CiAgKSArCiAgZ2VvbV9wb2ludChhZXMoCiAgICB4ID0gaml0dGVyKGxvbiksCiAgICB5ID0gaml0dGVyKGxhdCksCiAgICBjb2xvciA9IG1heF9qb2IsCiAgICBzaXplID0gbWF4CiAgKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIgPSAiIzAwQjJFNCIsCiAgICAgICJEYXRhIEFuYWx5c3QiID0gIiMwRjJBNDgiLAogICAgICAiRGF0YSBFbmdpbmVlciIgPSAiIzAwOEI4QiIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIgPSAiI0ZDMjk2NyIKICAgICksCiAgICBuYW1lID0gIkpvYiBUaXRsZSIKICApICsKICB0aGVtZSgKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAjbGVnZW5kLnBvc2l0aW9uID0gYygwLDApLCBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwwKQogICkgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICIiLAogICAgICAgdGl0bGUgPSAiIiwKICAgICAgIHNpemUgPSAiTnVtYmVyIikKYGBgCgpgYGB7cn0KZ2dwbG90KHBvaW50c19mbCkgKwogIGdlb21fc2YoCiAgICBkYXRhID0gc3RhdGVfbWFwc19mbCwKICAgIGNvbG9yID0gIndoaXRlIiwKICAgIGZpbGwgPSAibGlnaHRncmV5IiwKICAgIGFscGhhID0gMC41CiAgKSArCiAgZ2VvbV9wb2ludChhZXMoCiAgICB4ID0gaml0dGVyKGxvbiksCiAgICB5ID0gaml0dGVyKGxhdCksCiAgICBjb2xvciA9IG1heF9qb2IsCiAgICBzaXplID0gbWF4CiAgKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIgPSAiIzAwQjJFNCIsCiAgICAgICJEYXRhIEFuYWx5c3QiID0gIiMwRjJBNDgiLAogICAgICAiRGF0YSBFbmdpbmVlciIgPSAiIzAwOEI4QiIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIgPSAiI0ZDMjk2NyIKICAgICksCiAgICBuYW1lID0gIkpvYiBUaXRsZSIKICApICsKICB0aGVtZSgKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAjbGVnZW5kLnBvc2l0aW9uID0gYygwLDApLCBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwwKQogICkgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICIiLAogICAgICAgdGl0bGUgPSAiIiwKICAgICAgIHNpemUgPSAiTnVtYmVyIikKYGBgCgpgYGB7cn0KZ2dwbG90KHBvaW50c193YSkgKwogIGdlb21fc2YoCiAgICBkYXRhID0gc3RhdGVfbWFwc193YSwKICAgIGNvbG9yID0gIndoaXRlIiwKICAgIGZpbGwgPSAibGlnaHRncmV5IiwKICAgIGFscGhhID0gMC41CiAgKSArCiAgZ2VvbV9wb2ludChhZXMoCiAgICB4ID0gaml0dGVyKGxvbiksCiAgICB5ID0gaml0dGVyKGxhdCksCiAgICBjb2xvciA9IG1heF9qb2IsCiAgICBzaXplID0gbWF4CiAgKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKAogICAgICAiQnVzaW5lc3MgQW5hbHlzdCIgPSAiIzAwQjJFNCIsCiAgICAgICJEYXRhIEFuYWx5c3QiID0gIiMwRjJBNDgiLAogICAgICAiRGF0YSBFbmdpbmVlciIgPSAiIzAwOEI4QiIsCiAgICAgICJEYXRhIFNjaWVudGlzdCIgPSAiI0ZDMjk2NyIKICAgICksCiAgICBuYW1lID0gIkpvYiBUaXRsZSIKICApICsKICB0aGVtZSgKICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAjbGVnZW5kLnBvc2l0aW9uID0gYygwLDApLCBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwwKQogICkgKwogIGxhYnMoeCA9ICIiLAogICAgICAgeSA9ICIiLAogICAgICAgdGl0bGUgPSAiIiwKICAgICAgIHNpemUgPSAiTnVtYmVyIikKYGBgCgpgYGB7cn0KREFUQSAlPiUKICBmaWx0ZXIod29ya3NpdGVfc3RhdGVfYWJiID09ICJUTiIpICU+JQogIGdyb3VwX2J5KHllYXIsIGRhdGFfcmVsYXRpb24pICU+JQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUKICAKICBnZ3Bsb3QoYWVzKAogICAgeCA9IHllYXIsCiAgICB5ID0gbiwKICAgIGZpbGwgPSBhcy5mYWN0b3IoZGF0YV9yZWxhdGlvbikKICApKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsCiAgICAgICAgICAgcG9zaXRpb24gPSAiZG9kZ2UiLAogICAgICAgICAgIGFscGhhID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSBjKCIjMDBCMkU0IiwgIiMwRjJBNDgiKSwKICAgIG5hbWUgPSAiIiwKICAgIGxhYmVscyA9IGMoIkRhdGEgam9icyIsICJPdGhlcnMiKQogICkgKwogIGxhYnMoeSA9ICJcbiBOdW1iZXIiLCB4ID0gIlxuIFllYXIiKSArCiAgI3NjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBmdW5jdGlvbih4KXtwYXN0ZTAoeC8xMDAwLCAnSycpfSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikKYGBg